This demo illustrates how to control the properties of each audio track in a movie. The program is broken into several classes and a few packages.
MusicMixer class: This is the main class. It's pretty simple. It opens the movie file, and passes the movie off to the appropriate classes to make the mixer.
package mixer:
MixerDialog class: This is our method of displaying information to the user. It simply takes the component that contains the controls you want to present to the user, and displays them in a dialog box. Modifications to this class could allow you to present the information in several different ways. Perhaps you want to present all of the controls in one window. Modifications to this class (and probably the arguments to the constructor) would be the place to start.
package mixer.display:
ChannelDisplay class: This is the base class of most of our classes which determine how the control panels look when presented to the window (individual MIDI instrument channels are dealt with specially). The Display classes form the JComponent that is given to the MixerDialogs for displaying to the user. Given a choice of which buttons to produce, this class can create a control panel for any MixerComponents object. Subclasses can customize which buttons are available and how they perform simply by telling this constructor which buttons to provide and then overriding the default add*Action methods, which provide listeners for the controls.
MasterDisplay class: This is a subclass of ChannelDisplay which is used specifically for dealing with the master control of a movie, which only allows mute and volume controls. It creates a JPanel with the desired controls, and empty spaces for the remaining things.
SoundTrackDisplay class: This subclass of ChannelDisplay is used for displaying the standard mixer controls for sound and music tracks. Those tracks allow all of the editting buttons, so this class must provide overriden add*Action methods for all commands.
MusicPartDisplay class: This Display class is not a subclass of ChannelDisplay. It provides a different set of controls in a different format, and so is dealt with specially. This class illustrates how easy it is to change the format of the display and customize what it is that the user sees when mixing the movie.
SoloableChannels class: This class is really just a wrapper for the set of tracks on which a "solo" operation is possible. We needed a method for all of the channels to communicate with each other even though they know nothing about each other. This class just creates the SoundTrackDisplays for each channel and creates a panel with all of those controls.
package mixer.mc:
MixerComponents interface: This interface is the heart of our mixer. Any object that implements this interface can have a mixer created for it, assuming that there is an appropriate way of displaying it. Notice that all of our Display classes use a MixerComponents object when creating the display component. Using this technique, it is possible to do things such as grouping several sound tracks in a movie together (perhaps the same text, spoken in a different language in each track), and create a mixer out of them simply by providing an appropriate MixerComponents implementation, and creating a Display class appropriate for your project.
MixerMovie class: This implementation of the MixerComponents interface is used when creating the mixer for the master control of the movie (the actual player, in our case).
MixerSoundTrack class: This implementation of the MixerComponents interface is designed for use with the sound tracks in a movie. It knows the details about sound tracks, like that they cannot be editted any further and they have no children channels.
MixerMusicTrack class: This is another implementation of the MixerComponents interface which gives us the capability of dealing with MusicMedia tracks in movies. These tracks do contain child parts and can be edited further. By creating the appropriate makeEditComponent method, we control what happens when the edit button is clicked on. In this case, instead of creating a SoloableChannels or a MasterDisplay, we create a MusicPartDisplay. This is how easy it is to change what you use to display the controls to the user.
MixerMusicPart class: This implementation of MixerComponents is for use with the NoteChannels inside of a MusicMedia. This class knows that Music instrument parts cannot be edited (at least in this version of the mixer) and have no child channels.
LIMITATIONS:
NoteChannels do not hold their characteristics when the a movie is stopped and started, or when the time is changed. They reset themselves back to a default state. This means that any panning, volume, and mute characteristics you may have set on the individual instrument channels in a MusicMedia track will be lost when any of the above mentioned actions take place. This is a feature of Quicktime - the current MusicParts interact with the NoteChannels not the media which is kept in the Movie. With a future release of QuickTime it is anticipated that it will be possible to interact with the MusicMedia itself and thus have the changes persist and writable to a movie.
A QTSession.open will perform a gestalt check to ensure that QuickTime is present and is initialized. This is a required call before any QuickTime Java classes can be used.
When the user closes the window the program will quit, first calling QTSession.close to terminate QuickTime. It is necessary for programs to call QTSession.close if they have previously called QTSession.open in order to shut down QuickTime properly.